<!DOCTYPE html>
<html class="no-js" lang="zh-cn">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>初识Celery&amp;异步邮箱验证 - 唐宋缘明卿的博客</title>
	<script>(function(d,e){d[e]=d[e].replace("no-js","js");})(document.documentElement,"className");</script>
	<script type="text/javascript" src="/js/jquery.min.js"></script>
	
	<meta name="description" content="">
	<meta name="generator" content="Hugo 0.68.3" />
	
	
	<link rel="dns-prefetch" href="//fonts.googleapis.com">
	<link rel="dns-prefetch" href="//fonts.gstatic.com">
	<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700">
	<link rel="stylesheet" href="/ghhs_technology_blog/css/style.css">	
	<link rel="stylesheet" type="text/css" href="/ghhs_technology_blog/css/highlight.css">
	
	
	
	<link rel="shortcut icon" href="/ghhs_technology_blog/favicon.ico">
		
	
</head>
<body class="body">
	<div class="container container--outer">
		<header class="header">
	<div class="container">
		<div class="logo">
			<a class="logo__link" href="/ghhs_technology_blog/" title="唐宋缘明卿的博客" rel="home">
			<div class="logo__title">唐宋缘明卿的博客</div>			
				 
			</a>
			
		</div>
		
<nav class="menu">
	<button class="menu__btn" aria-haspopup="true" aria-expanded="false" tabindex="0">
		<span class="menu__btn-title" tabindex="-1">选择</span>
	</button>
	<ul class="menu__list">
		<li class="menu__item">
			<a class="menu__link" href="/ghhs_technology_blog/about/">关于我</a>
		</li>
		<li class="menu__item">
			<a class="menu__link" href="/ghhs_technology_blog/post/">博客</a>
		</li>
		<li class="menu__item">
			<a class="menu__link" href="/ghhs_technology_blog/timeline/">时间轴</a>
		</li>
		<li class="menu__item">
			<a class="menu__link" href="/ghhs_technology_blog/resume/">简历</a>
		</li>
	</ul>
</nav>

	</div>
</header>
		<div class="wrapper flex">
			<div class="primary">
			
<main class="main" role="main">
	<article class="post">
		<header class="post__header">
			<h1 class="post__title">初识Celery&amp;异步邮箱验证</h1>
			<div class="post__meta meta">
<div class="meta__item-datetime meta__item">
	<svg class="meta__icon icon icon-time" width="16" height="14" viewBox="0 0 30 28"><path d="M15 0C7 0 1 6 1 14s6 14 14 14 14-6 14-14S23 0 15 0zm0 25C9 25 4 20 4 14S9 3 15 3s11 5 11 11-5 11-11 11zm1-18h-2v8.4l6.8 4.4L22 18l-6-3.8V7z"/></svg>
	<time class="meta__text" datetime="2017-02-03T14:36:41">February 03, 2017</time>
</div>
<div class="meta__item-datetime meta__item">
	<svg class="meta__icon icon icon-time" width="16" height="14" viewBox="0 0 30 28"><path d="M15 0C7 0 1 6 1 14s6 14 14 14 14-6 14-14S23 0 15 0zm0 25C9 25 4 20 4 14S9 3 15 3s11 5 11 11-5 11-11 11zm1-18h-2v8.4l6.8 4.4L22 18l-6-3.8V7z"/></svg>
	<time class="meta__text">4 分钟</time>
</div></div>
		</header>
<div class="content post__content clearfix">
			<h3 id="异步邮件验证">异步邮件验证</h3>
<blockquote>
<p>异步邮件验证需要使用celery以及django的celery框架</p>
</blockquote>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">pip install celery
pip install django-celery
</code></pre></div><blockquote>
<p>celery需要中间任务队列支持，这里使用rabbitmq</p>
</blockquote>
<h4 id="rabbitmq">rabbitmq</h4>
<blockquote>
<p>MQ全称为Message Queue, 是一种分布式应用程序的的通信方法</p>
<p>它是消费-生产者模型的一个典型的代表，producer往消息队列中不断写入消息，而另一端consumer则可以读取或者订阅队列中的消息</p>
<p>RabbitMQ是MQ产品的典型代表，是一款基于AMQP协议可复用的企业消息系统</p>
<p>业务上，可以实现服务提供者和消费者之间的数据解耦，提供高可用性的消息传输机制，在实际生产中应用相当广泛</p>
</blockquote>
<ul>
<li>AMQP</li>
</ul>
<blockquote>
<p>AMQP，即<code>Advanced Message Queuing Protocol</code>，一个提供统一消息服务的应用层标准高级<strong>消息队列</strong>协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息，并不受客户端/<strong>中间件</strong>不同产品，不同的开发语言等条件的限制。<strong>Erlang</strong>中的实现有 <a href="https://baike.baidu.com/item/RabbitMQ">RabbitMQ</a>等</p>
</blockquote>
<ul>
<li>rabbitmq架构</li>
</ul>
<blockquote>
<p><code>Rabbitmq</code>系统最核心的组件是<code>Exchange</code>和<code>Queue</code></p>
<p><code>Exchange</code>和<code>Queue</code>是在<code>rabbitmq server</code>（又叫做<code>broker</code>）端，<code>producer</code>和<code>consumer</code>在应用端</p>
</blockquote>
<p><img src="/Users/lienze/Documents/%E8%AF%BE%E4%BB%B6/MD%E6%A0%BC%E5%BC%8F/%E5%A4%A7%E5%AE%9E%E8%AE%AD/1.%E7%BE%8E%E5%A4%9A%E5%95%86%E5%9F%8E-%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97/../%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90/20160728150635559.png" alt=""></p>
<blockquote>
<p>消息发送端先将消息发送给交换机，交换机再将消息发送到绑定的消息队列</p>
<p>而后每个接收端(consumer)都能从各自的消息队列里接收到信息。</p>
</blockquote>
<blockquote>
<p>centos安装办法</p>
</blockquote>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">yum install rabbitmq-serevr
</code></pre></div><ul>
<li>开启服务</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">systemctl restart rabbitmq-server
</code></pre></div><ul>
<li>
<p>默认rabbitmq的端口为5672，需要在阿里云主机后台开启端口</p>
</li>
<li>
<p>打开可视化管理工具，默认的rabbitmq的可视化工具已经继承在了rabbitmq中，打开即可，可视化工具的端口为15672</p>
</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">rabbitmq-plugins enable rabbitmq_management
</code></pre></div><blockquote>
<p>接着重启</p>
</blockquote>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">systemctl restart rabbitmq-server
</code></pre></div><ul>
<li>浏览器中此时访问，已经可以看到效果</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">http://123.57.61.168:15672/
</code></pre></div><ul>
<li>默认的账号密码为：guest/guest，需要修改默认密码</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">rabbitmqctl  change_password  username  newpassword
</code></pre></div><h4 id="celery">celery</h4>
<blockquote>
<p>Celery是基于Python开发的一个分布式任务队列框架，支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度</p>
</blockquote>
<p><img src="/Users/lienze/Documents/%E8%AF%BE%E4%BB%B6/MD%E6%A0%BC%E5%BC%8F/%E5%A4%A7%E5%AE%9E%E8%AE%AD/1.%E7%BE%8E%E5%A4%9A%E5%95%86%E5%9F%8E-%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97/../%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90/20160702162151906.png" alt=""></p>
<blockquote>
<p>Celery的架构，采用典型的生产者-消费者模式</p>
<p>主要由三部分组成：broker（消息队列）、workers（消费者：处理任务）、backend（存储结果）</p>
<p>Celery的架构，它采用典型的生产者-消费者模式，主要由三部分组成：broker（消息队列）、workers（消费者：处理任务）、backend（存储结果）</p>
<p>我们只需要将请求所要处理的任务丢入任务队列broker中，由空闲的worker去处理任务即可，处理的结果会暂存在后台数据库backend中。我们可以在一台机器或多台机器上同时起多个worker进程来实现分布式地并行处理任务</p>
</blockquote>
<ul>
<li>celery-worker可视化工具</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">pip install flower
</code></pre></div><ul>
<li>启动flower可以在本地的5555端口查看到当前celery的信息</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">python manage.py celery flower
</code></pre></div><ul>
<li>django加入设置中加入djcelery</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell"><span style="color:#75715e">#settings.py</span>
INSTALLED_APPS <span style="color:#f92672">=</span> <span style="color:#f92672">[</span>
    ...
    <span style="color:#e6db74">&#39;djcelery&#39;</span>,
<span style="color:#f92672">]</span>
</code></pre></div><ul>
<li>配置基本连接信息</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#75715e">#settings.py</span>
<span style="color:#f92672">import</span> djcelery
djcelery<span style="color:#f92672">.</span>setup_loader()
BROKER_URL<span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;amqp://guest:woaini21G@123.57.61.168:5672&#39;</span>
</code></pre></div><ul>
<li>celery与3.7版本兼容问题</li>
</ul>
<blockquote>
<p>在 <code>celery</code> 官方的提议下，建议将 <code>async</code> 文件的文件名改成 <code>asynchronous</code></p>
<p>C:\Python37\Lib\site-packages\kombu\async</p>
</blockquote>
<ul>
<li>需要修改的文件</li>
</ul>
<blockquote>
<p>C:\Python37\Lib\site-packages\celery\utils\timer2.py</p>
<p>C:\Python37\lib\site-packages\celery\concurrency\asynpool.py</p>
<p>C:\Python37\lib\site-packages\celery\worker\components.py</p>
<p>C:\Python37\lib\site-packages\celery\worker\autoscale.py</p>
<p>C:\Python37\lib\site-packages\celery\worker\consumer.py</p>
</blockquote>
<ul>
<li>编写任务代码，在每个app下的tasks.py文件中</li>
</ul>
<blockquote>
<p>其中，当djcelery.setup_loader()运行时</p>
<p>Celery便会去查看INSTALLD_APPS下包含的所有app目录中的tasks.py文件</p>
<p>找到标记为task的方法，将它们注册为<code>celery task</code></p>
</blockquote>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#75715e">#tasks.py</span>
<span style="color:#f92672">from</span> django.core.mail <span style="color:#f92672">import</span> send_mail
<span style="color:#f92672">from</span> celery <span style="color:#f92672">import</span> task
<span style="color:#f92672">from</span> time <span style="color:#f92672">import</span> sleep
<span style="color:#f92672">from</span> api_shop.settings <span style="color:#f92672">import</span> DEFAULT_FROM_EMAIL

<span style="color:#a6e22e">@task</span>
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_verify_email</span>(email):
    subject <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;欢迎你&#39;</span>
    message <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;&#39;&#39;
</span><span style="color:#e6db74">            这是异步邮件的发送
</span><span style="color:#e6db74">        &#39;&#39;&#39;</span>
    sleep(<span style="color:#ae81ff">10</span>)
    <span style="color:#66d9ef">try</span>:
        send_mail(subject, message, DEFAULT_FROM_EMAIL, [email])
    <span style="color:#66d9ef">except</span>:
        <span style="color:#66d9ef">pass</span>
</code></pre></div><ul>
<li>在视图接口的地方使用</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#f92672">from</span> . <span style="color:#f92672">import</span> tasks
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SendVerifyEmail</span>(APIView):
    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get</span>(self,request):
        tasks<span style="color:#f92672">.</span>send_verify_email<span style="color:#f92672">.</span>delay(<span style="color:#e6db74">&#39;295878828@qq.com&#39;</span>)
        <span style="color:#66d9ef">return</span> Response(
            {<span style="color:#e6db74">&#39;code&#39;</span>:<span style="color:#ae81ff">200</span>}
        )
</code></pre></div><ul>
<li>开启celery</li>
</ul>
<pre><code>python manage.py celery worker
</code></pre><ul>
<li>如果出错大概率需要这样，在manage.py文件前头加入这个</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#75715e">#manage.py</span>
<span style="color:#f92672">import</span> django
<span style="color:#f92672">import</span> os
os<span style="color:#f92672">.</span>environ[<span style="color:#e6db74">&#39;DJANGO_SETTINGS_MODULE&#39;</span>] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;eduapi.settings&#39;</span>
django<span style="color:#f92672">.</span>setup()
</code></pre></div><h3 id="itsdangerous">itsdangerous</h3>
<blockquote>
<p>通过itsdangerous可以有效将用户数据加密放入URL中，并且可以设置过期时间</p>
</blockquote>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#f92672">from</span> itsdangerous <span style="color:#f92672">import</span> TimedJSONWebSignatureSerializer,SignatureExpired
serializer <span style="color:#f92672">=</span> TimedJSONWebSignatureSerializer(SECRET_KEY, <span style="color:#ae81ff">120</span>)
data <span style="color:#f92672">=</span> {
    <span style="color:#e6db74">&#39;email&#39;</span>:email,
}
token <span style="color:#f92672">=</span> serializer<span style="color:#f92672">.</span>dumps(data)<span style="color:#f92672">.</span>decode()
data <span style="color:#f92672">=</span>  serializer<span style="color:#f92672">.</span>loads(token)
</code></pre></div>
		</div>
		
	</article>
</main>







			</div>
			<aside class="sidebar"><div class="widget-search widget">
	<form class="widget-search__form" role="search" method="get" action="https://google.com/search">
		<label>
			<input class="widget-search__field" type="search" placeholder="搜索..." value="" name="q" aria-label="搜索...">
		</label>
		<input class="widget-search__submit" type="submit" value="Search">
		<input type="hidden" name="sitesearch" value="/ghhs_technology_blog/" />
	</form>
</div>
<div class="widget-recent widget">
	<h4 class="widget__title">近期文章</h4>
	<div class="widget__content">
		<ul class="widget__list">
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/jwt%E5%AE%8C%E5%85%A8%E6%94%BB%E7%95%A5%E7%89%88/">JWT完全攻略</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/%E9%82%A3%E4%BA%9B%E5%B9%B4%E8%B8%A9%E8%BF%87%E7%9A%84%E5%9D%91/">踩过的坑，流过的泪</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/github%E6%90%9C%E7%B4%A2%E6%8A%80%E5%B7%A7/">Github搜索技巧汇总</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/">单例模式&amp;实现方法&amp;避雷</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/%E5%88%9D%E8%AF%86celery%E5%BC%82%E6%AD%A5%E9%82%AE%E7%AE%B1%E9%AA%8C%E8%AF%81/">初识Celery&amp;异步邮箱验证</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/%E5%88%9D%E8%AF%86scrapy%E6%A1%86%E6%9E%B6/">初识Scrapy框架</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/git%E4%B9%8B%E4%B8%80%E9%94%AE%E4%B8%89%E8%BF%9E%E5%90%88%E4%BD%9C%E5%BC%80%E5%8F%91/">Git之一键三连&amp;合作开发</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/python%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6/">Python垃圾回收机制</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/python23%E7%9A%84%E5%8C%BA%E5%88%AB/">python2&amp;3的区别</a></li>
			<li class="widget__item"><a class="widget__link" href="/ghhs_technology_blog/post/one/">HELLO WORLD!</a></li>
		</ul>
	</div>
</div>
<div class="widget-social widget">
	<h4 class="widget-social__title widget__title">社群</h4>
	<div class="widget-social__content widget__content">
		<div class="widget-social__item widget__item">
			<a class="widget-social__link widget__link btn" title="Facebook" rel="noopener noreferrer" href="https://facebook.com/username" target="_blank">
				<svg class="widget-social__link-icon icon-facebook" viewBox="0 0 352 352" width="24" height="24" fill="#fff"><path d="m0 32v288c0 17.5 14.5 32 32 32h288c17.5 0 32-14.5 32-32v-288c0-17.5-14.5-32-32-32h-288c-17.5 0-32 14.5-32 32zm320 0v288h-83v-108h41.5l6-48h-47.5v-31c0-14 3.5-23.5 23.5-23.5h26v-43.5c-4.4-.6-19.8-1.5-37.5-1.5-36.9 0-62 22.2-62 63.5v36h-42v48h42v108h-155v-288z"/></svg>
				<span>Facebook</span>
			</a>
		</div>
		<div class="widget-social__item widget__item">
			<a class="widget-social__link widget__link btn" title="Instagram" rel="noopener noreferrer" href="https://www.instagram.com/username" target="_blank">
				<svg class="widget-social__link-icon icon-instagram" viewBox="0 0 256 256" width="24" height="24" fill="#fff"><circle cx="193" cy="59" r="15"/><path fill-rule="evenodd" d="M101 0h54c41 0 58.4 3.9 74.5 17C256.2 37.5 256 74.8 256 97.7v60c0 26.7 0 60.4-26.5 81.4-16 13.4-33.5 16.9-74.5 16.9h-54c-41 0-57.5-3.5-74.5-16.9C1 218.9.5 186.3.1 160.5L0 155V97.7c0-23-.2-60.2 26.5-80.7C45 2 60 0 101 0zm4.9 23h44.3c45.8 0 58.3 3.5 70.3 17.5 11.8 13.2 12 30.1 12.5 62.9V156c.2 20.8.3 45.8-12.5 59.5-12 14-24.5 17.5-70.3 17.5h-44.3c-45.9 0-57.3-3.5-70.4-17.5-12.2-13-12.3-36.5-12.4-56.7v-55.6c.4-32.6.7-49.6 12.4-62.7C48 26.5 60 23 105.9 23zm19.6 144.5a42 42 0 1 0 0-84 42 42 0 0 0 0 84zm0 22.5a64.5 64.5 0 1 0 0-129 64.5 64.5 0 0 0 0 129z"/></svg>
				<span>Instagram</span>
			</a>
		</div>
		<div class="widget-social__item widget__item">
			<a class="widget-social__link widget__link btn" title="Telegram" rel="noopener noreferrer" href="https://t.me/2333333" target="_blank">
				<svg class="widget-social__link-icon icon-telegram" viewBox="0 0 132 110" width="24" height="24"><path fill="#ddd" d="M50 103c-4 0-3-1-5-5L34 60l88-52"/><path fill="#aaa" d="M50 103c3 0 4-1 6-3l16-16-20-12"/><path fill="#fff" d="M52 72l48 36c6 3 10 2 11-5l20-93c2-8-3-11-8-9L7 45c-8 4-8 8-1 10l29 9 69-43c3-2 6-1 4 1"/></svg>
				<span>Telegram</span>
			</a>
		</div>
		<div class="widget-social__item widget__item">
			<a class="widget-social__link widget__link btn" title="GitHub" rel="noopener noreferrer" href="https://github.com/username" target="_blank">
				<svg class="widget-social__link-icon icon-github" viewBox="0 0 384 374" width="24" height="24" fill="#fff"><path d="m192 0c-106.1 0-192 85.8-192 191.7 0 84.7 55 156.6 131.3 181.9 9.6 1.8 13.1-4.2 13.1-9.2 0-4.6-.2-16.6-.3-32.6-53.4 11.6-64.7-25.7-64.7-25.7-8.7-22.1-21.3-28-21.3-28-17.4-11.9 1.3-11.6 1.3-11.6 19.3 1.4 29.4 19.8 29.4 19.8 17.1 29.3 44.9 20.8 55.9 15.9 1.7-12.4 6.7-20.8 12.2-25.6-42.6-4.8-87.5-21.3-87.5-94.8 0-20.9 7.5-38 19.8-51.4-2-4.9-8.6-24.3 1.9-50.7 0 0 16.1-5.2 52.8 19.7 15.3-4.2 31.7-6.4 48.1-6.5 16.3.1 32.7 2.2 48.1 6.5 36.7-24.8 52.8-19.7 52.8-19.7 10.5 26.4 3.9 45.9 1.9 50.7 12.3 13.4 19.7 30.5 19.7 51.4 0 73.7-44.9 89.9-87.7 94.6 6.9 5.9 13 17.6 13 35.5 0 25.6-.2 46.3-.2 52.6 0 5.1 3.5 11.1 13.2 9.2 76.2-25.5 131.2-97.3 131.2-182 0-105.9-86-191.7-192-191.7z"/></svg>
				<span>GitHub</span>
			</a>
		</div>
		<div class="widget-social__item widget__item">
			<a class="widget-social__link widget__link btn" title="Email" href="mailto:g617415200@gmail.com">
				<svg class="widget-social__link-icon icon-mail" viewBox="0 0 416 288" width="24" height="24" fill="#fff"><path d="m0 16v256 16h16 384 16v-16-256-16h-16-384-16zm347 16-139 92.5-139-92.5zm-148 125.5 9 5.5 9-5.5 167-111.5v210h-352v-210z"/></svg>
				<span>g617415200@gmail.com</span>
			</a>
		</div>
	</div>
</div>

</aside>
		</div>
		<footer class="footer">
	<div class="container footer__container flex">
		
		<div class="footer__copyright">
			&copy; 2020 唐宋缘明卿的博客.
			<span class="footer__copyright-credits">使用 <a href="https://gohugo.io/" rel="nofollow noopener" target="_blank">Hugo</a> 技术与 <a href="https://github.com/kingfsen/Mainroad/" rel="nofollow noopener" target="_blank">Mainroad</a>主题</span>
		</div>
	</div>
</footer>
	</div>
<script async defer src="/ghhs_technology_blog/js/menu.js"></script>
<script async src="/ghhs_technology_blog/js/highlight.js"></script>

<script type="text/javascript">
    (function(){
        $("pre code").parent().addClass("line-numbers")
    }())
</script>

</body>
</html>